package order

import (
	"context"
	"fmt"
	"strconv"
	"time"

	"gitee.com/wenchangshou/simple-admin-pancakebot-rpc/ent"
	"gitee.com/wenchangshou/simple-admin-pancakebot-rpc/ent/pancakebotorder"
	"gitee.com/wenchangshou/simple-admin-pancakebot-rpc/internal/svc"
	"gitee.com/wenchangshou/simple-admin-pancakebot-rpc/internal/utils/dberrorhandler"
	"gitee.com/wenchangshou/simple-admin-pancakebot-rpc/types/pancakebot"
	"github.com/agui-coder/simple-admin-pay-rpc/types/pay"
	"github.com/suyuan32/simple-admin-common/enum/common"
	"github.com/suyuan32/simple-admin-common/i18n"
	"github.com/suyuan32/simple-admin-common/utils/pointy"

	"github.com/zeromicro/go-zero/core/errorx"
	"github.com/zeromicro/go-zero/core/logx"
)

type UpdatePancakebotOrderPaidLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewUpdatePancakebotOrderPaidLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdatePancakebotOrderPaidLogic {
	return &UpdatePancakebotOrderPaidLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *UpdatePancakebotOrderPaidLogic) UpdatePancakebotOrderPaid(in *pancakebot.UpdatePancakebotOrderPaidReq) (*pancakebot.BaseResp, error) {
	logx.Infof("update paid orderId:%d", in.Id)

	// 2. 查询煎饼订单
	pancakebotOrder, err := l.svcCtx.DB.PancakebotOrder.Get(l.ctx, in.Id)
	var orderStatus common.OrderStatus
	if err != nil {
		return nil, dberrorhandler.DefaultEntError(l.Logger, err, in)
	}

	// 2. 验证订单是否处于待支付状态
	if pancakebotOrder.PayStatus {
		logx.Errorf("[UpdatePancakebotOrderPaid][order(%d) 不处于待支付状态，请进行处理！order 数据是：%+v]", pancakebotOrder.ID, pancakebotOrder)
		return nil, errorx.NewInvalidArgumentError("PANCAKEBOT_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID")
	}

	// 3. 验证支付订单号是否匹配
	if pancakebotOrder.PayOrderId != in.PayOrderId {
		logx.Errorf("[UpdatePancakebotOrderPaid][order(%d) 支付订单号不匹配，请进行处理！order 数据是：%+v]", pancakebotOrder.ID, pancakebotOrder)
		return nil, errorx.NewInvalidArgumentError("PANCAKEBOT_ORDER_UPDATE_PAID_PAY_ORDER_ID_NOT_MATCH")
	}
	// 4. 查询支付订单详情
	payOrder, err := l.svcCtx.PayRpc.GetOrder(l.ctx, &pay.IDReq{Id: in.PayOrderId})
	if err != nil {
		return nil, dberrorhandler.DefaultEntError(l.Logger, err, in)
	}

	// 5. 验证支付订单是否已支付成功
	if uint8(pay.PayStatus_PAY_SUCCESS) != *pointy.GetStatusPointer(payOrder.Status) {
		logx.Errorf("[UpdatePancakebotOrderPaid][order(%d) 支付订单未支付，请进行处理！payOrder 数据是：%+v]", pancakebotOrder.ID, payOrder)
		return nil, errorx.NewInvalidArgumentError("PANCAKEBOT_ORDER_UPDATE_PAID_PAY_ORDER_NOT_PAID")
	}

	// 6. 验证支付金额是否匹配
	payOrderPrice := int32(*payOrder.Price)
	pancakebotOrderPrice := int32(pancakebotOrder.Price * 100)
	if payOrderPrice != pancakebotOrderPrice {
		logx.Errorf("[UpdatePancakebotOrderPaid][order(%d) 支付订单金额不匹配，请进行处理！payOrder.Price=%d, pancakebotOrder.Price=%d]",
			pancakebotOrder.ID, payOrderPrice, pancakebotOrderPrice)
		return nil, errorx.NewInvalidArgumentError("PANCAKEBOT_ORDER_UPDATE_PAID_PAY_ORDER_PRICE_NOT_MATCH")
	}

	// 7. 验证商户订单号是否匹配
	if *payOrder.MerchantOrderId != strconv.FormatUint(pancakebotOrder.ID, 10) {
		logx.Errorf("[UpdatePancakebotOrderPaid][order(%d) 支付订单商户订单号不匹配，请进行处理！payOrder.MerchantOrderId=%s]",
			pancakebotOrder.ID, *payOrder.MerchantOrderId)
		return nil, errorx.NewInvalidArgumentError("PANCAKEBOT_ORDER_UPDATE_PAID_PAY_ORDER_MERCHANT_ORDER_ID_NOT_MATCH")
	}
	orderStatus = common.OrderStatusPaid
	//pancakebotOrder.DeviceID
	deviceResp, err := l.svcCtx.DB.Device.Get(l.ctx, pancakebotOrder.DeviceID)
	if err != nil {
		return nil, dberrorhandler.DefaultEntError(l.Logger, err, in)
	}

	for idx_, outlet := range deviceResp.OutletPorts {
		if !outlet.InUse && outlet.Status == int(common.OutletPortStatusActive) {
			logx.Infof("orderId:%d,分配出餐口:%d", in.Id, outlet.Number)
			deviceResp.OutletPorts[idx_].InUse = true
			err = l.svcCtx.DB.Device.UpdateOneID(deviceResp.ID).
				SetOutletPorts(deviceResp.OutletPorts).
				Exec(l.ctx)

			if err != nil {
				return nil, dberrorhandler.DefaultEntError(l.Logger, err, in)
			}
			orderStatus = common.OrderStatusToMake
			break
		}
	}
	// 8. 查询当天最大订单号并加1
	nextOrderNo, err := l.getNextOrderNo()
	if err != nil {
		return nil, dberrorhandler.DefaultEntError(l.Logger, err, in)
	}
	logx.Infof("生成新订单号: %d", nextOrderNo)

	// 9. 更新订单支付状态和订单号
	err = l.svcCtx.DB.PancakebotOrder.UpdateOneID(in.Id).
		SetPayStatus(true).
		SetPayTime(time.Now()).
		SetOrderStatus(int64(orderStatus)).
		SetPayChannelCode(*payOrder.ChannelCode).
		SetOrderNo(nextOrderNo).
		Exec(l.ctx)

	if err != nil {
		return nil, dberrorhandler.DefaultEntError(l.Logger, err, in)
	}

	logx.Infof("订单支付成功, 订单ID: %d, 订单号: %d, 订单状态: %d", in.Id, nextOrderNo, orderStatus)
	return &pancakebot.BaseResp{Msg: i18n.UpdateSuccess}, nil
}

// getNextOrderNo 获取下一个订单号（查询当天最大订单号+1）
func (l *UpdatePancakebotOrderPaidLogic) getNextOrderNo() (uint64, error) {
	// 获取当天的开始时间（0点）
	now := time.Now()
	startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())

	// 获取当天的结束时间（23:59:59）
	endOfDay := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 999999999, now.Location())

	// 查询当天订单号最大的订单（按 order_no 降序，取第一个）
	maxOrder, err := l.svcCtx.DB.PancakebotOrder.Query().
		Where(
			pancakebotorder.CreatedAtGTE(startOfDay),
			pancakebotorder.CreatedAtLTE(endOfDay),
			pancakebotorder.OrderNoGT(0), // 只查询有订单号的记录
		).
		Order(ent.Desc(pancakebotorder.FieldOrderNo)). // 降序排序
		First(l.ctx)

	// 如果没有找到订单（今天还没有订单或没有订单号）
	if err != nil {
		// 使用 ent 包的 IsNotFound 判断
		if ent.IsNotFound(err) {
			return 1, nil
		}
		// 其他错误返回
		return 0, fmt.Errorf("查询最大订单号失败: %w", err)
	}

	// 返回最大订单号+1
	return maxOrder.OrderNo + 1, nil
}
